package com.haotian.threadpool;

import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.apache.log4j.Logger;

import com.haotian.log.biz._BizLogUtils;

/**
 * 线程池工具类
 * 
 * @author zhanghaotian
 */
public class _ThreadPool {

	Logger logger = _BizLogUtils.getLogger(this.getClass());

	// 线程池类型常量
	/**
	 * 根据线程个数复用
	 */
	public static final String THREAD_TYPE_FIXED = "newFixedThreadPool";

	/**
	 * 根据时间循环执行 带延迟启动
	 */
	public static final String THREAD_TYPE_SCHEDULED = "newScheduledThreadPool";

	/**
	 * 延迟启动
	 */
	private Integer thread_delay = 2;
	/**
	 * 是否循环 循环间隔多少秒
	 */
	private Integer thread_period;

	/**
	 * 线程类型
	 */
	private String thread_type;

	/**
	 * 线程池最大数量
	 */
	private Integer thread_count = 0;

	// 线程池对象
	private ScheduledExecutorService scheduledService = null;

	private ExecutorService service = null;

	
	
	
	/**
	 * @param thread_type	线程类型	默认 {@link _ThreadPool.THREAD_TYPE_FIXED} 
	 * @param thread_count	线程数量	默认为CPU 线程数
	 * @param thread_delay	线程延迟启动秒数	只有当线程类型为{@link _ThreadPool.THREAD_TYPE_SCHEDULED} 的时候 才有效 默认为2
	 * @param thread_period	本字段值为null的时候 则关闭线程的循环执行run 方法的功能  否则为循环间隔秒数
	 */
	public _ThreadPool(String thread_type, Integer thread_count, Integer thread_delay, Integer thread_period) {

		if (thread_count != null && thread_count > 0) {
			this.thread_count = thread_count;
		} else {
			this.thread_count = Runtime.getRuntime().availableProcessors();
		}

		if (thread_type != null && thread_type.equals(THREAD_TYPE_SCHEDULED)) {
			scheduledService = Executors.newScheduledThreadPool(this.thread_count);
			this.thread_type = thread_type;
		} else {
			service = Executors.newFixedThreadPool(this.thread_count);
			this.thread_type = THREAD_TYPE_FIXED;
		}

		if (thread_delay != null) {
			this.thread_delay = thread_delay;
		}

		if (thread_period != null && thread_period > 0) {
			this.thread_period = thread_period;
		}
		logger.info("线程池初始化成功");
		logger.info("线程池类型：" + this.thread_type);
		logger.info("线程池数量：" + this.thread_count);

		if (scheduledService != null) {
			logger.info("线程启动延迟：" + this.thread_delay + "秒");
			if (this.thread_period == null) {
				logger.info("线程循环执行禁止");
			} else {
				logger.info("线程循环执行间隔:" + this.thread_period + "秒");
			}

		}

	}

	/**
	 * 向 线程池中压入 一个 Runnable
	 * 
	 * @param runnable
	 * @throws IOException
	 */
	public void run(Runnable runnable) throws Exception {

		if (service != null) {
			service.execute(runnable);
		} else {
			if (null == thread_period) {
				scheduledService.schedule(runnable, thread_delay, TimeUnit.SECONDS);
			} else {
				scheduledService.scheduleAtFixedRate(runnable, thread_delay, thread_period, TimeUnit.SECONDS);
			}
		}
	}

	/**
	 * 检测 当前线程池 是否关闭 如果关闭 返回 true
	 * 
	 * @return
	 */
	public boolean isShutDown() {
		if (service != null) {
			return service.isShutdown();
		} else {
			return scheduledService.isShutdown();
		}
	}

	/**
	 * 关闭线程池 停止 当前处理的 和排队中的 一切任务
	 */
	public void shutdown() {
		if (service != null) {
			service.shutdown();
			service.shutdownNow();
		} else {
			scheduledService.shutdown();
			scheduledService.shutdownNow();
		}
	}
}
